<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Spring扩展 | du小站</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="Spring扩展的简单示例">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring扩展">
<meta property="og:url" content="https://wenjies.github.io/2017/05/22/Spring%E6%89%A9%E5%B1%95/index.html">
<meta property="og:site_name" content="du小站">
<meta property="og:description" content="Spring扩展的简单示例">
<meta property="og:locale">
<meta property="article:published_time" content="2017-05-22T01:00:00.000Z">
<meta property="article:modified_time" content="2024-12-02T02:14:40.160Z">
<meta property="article:author" content="杰">
<meta property="article:tag" content="扩展">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="du小站" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/favicon.png">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
  
<meta name="generator" content="Hexo 7.3.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">du小站</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">我们笑着说再见，却深知再见遥遥无期。</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
        
          <a class="nav-icon" href="/atom.xml" title="RSS Feed"><span class="fa fa-rss"></span></a>
        
        <a class="nav-icon nav-search-btn" title="Suche"><span class="fa fa-search"></span></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Suche"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://wenjies.github.io"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-Spring扩展" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2017/05/22/Spring%E6%89%A9%E5%B1%95/" class="article-date">
  <time class="dt-published" datetime="2017-05-22T01:00:00.000Z" itemprop="datePublished">2017-05-22</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Spring/">Spring</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="p-name article-title" itemprop="headline name">
      Spring扩展
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h1 id="Spring扩展"><a href="#Spring扩展" class="headerlink" title="Spring扩展"></a>Spring扩展</h1><hr>
<h3 id="为什么要扩展"><a href="#为什么要扩展" class="headerlink" title="为什么要扩展"></a>为什么要扩展</h3><ol>
<li>做java开发Spring是必须要用的而且用的很频繁。</li>
<li>Spring的核心IOC和AOP是我们最想要的，但是有些时候需要把我们自定义的bean的生产过程，bean创建好之后再交给Spring容器。所以重点来了怎么交给它</li>
<li>其实Spring的设计早就考虑到这些问题了，只是平时没怎么使用而已，本文带你解开它神秘的面纱。</li>
</ol>
<h1 id="理论加实践"><a href="#理论加实践" class="headerlink" title="理论加实践"></a>理论加实践</h1><hr>
<h3 id="1-使用Component注解"><a href="#1-使用Component注解" class="headerlink" title="1.使用Component注解"></a>1.使用Component注解</h3><ol>
<li>想让Spring扫描我们自定义的注解很简单。只需要在我们的注解上加上 @org.springframework.stereotype.Component 代码如下:</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@Component</span><br><span class="line">@Retention(RetentionPolicy.RUNTIME)</span><br><span class="line">@Target(ElementType.TYPE)</span><br><span class="line">public @interface MyService &#123;</span><br><span class="line">	String value() default &quot;&quot;;// 必须要有</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>以上就可以让Spring扫描到我们的注解，作用和Spring的注解作用是一样的。 细心的同学可能已经发现<br>org.springframework.stereotype.Controller 的注解不就是这样实现的嘛。<br>让我们来看看这是为什么,在<br>org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider类中的registerDefaultFilters 方法中有<br>this.includeFilters.add(new AnnotationTypeFilter(Component.class))这样一句话，看到这里明白了吧 。代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">@SuppressWarnings(&quot;unchecked&quot;)</span><br><span class="line">protected void registerDefaultFilters() &#123;</span><br><span class="line">	this.includeFilters.add(new AnnotationTypeFilter(Component.class));</span><br><span class="line">	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();</span><br><span class="line">	try &#123;</span><br><span class="line">		this.includeFilters.add(new AnnotationTypeFilter(</span><br><span class="line">				((Class&lt;? extends Annotation&gt;) ClassUtils.forName(&quot;javax.annotation.ManagedBean&quot;, cl)), false));</span><br><span class="line">		logger.debug(&quot;JSR-250 &#x27;javax.annotation.ManagedBean&#x27; found and supported for component scanning&quot;);</span><br><span class="line">	&#125;</span><br><span class="line">	catch (ClassNotFoundException ex) &#123;</span><br><span class="line">		// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.</span><br><span class="line">	&#125;</span><br><span class="line">	try &#123;</span><br><span class="line">		this.includeFilters.add(new AnnotationTypeFilter(</span><br><span class="line">				((Class&lt;? extends Annotation&gt;) ClassUtils.forName(&quot;javax.inject.Named&quot;, cl)), false));</span><br><span class="line">		logger.debug(&quot;JSR-330 &#x27;javax.inject.Named&#x27; annotation found and supported for component scanning&quot;);</span><br><span class="line">	&#125;</span><br><span class="line">	catch (ClassNotFoundException ex) &#123;</span><br><span class="line">		// JSR-330 API not available - simply skip.</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>你以为这样就完了嘛？如果仅仅是装个x确实完了，被他注解的类会被Spring管理。 但是对于我们来讲是不够滴，应为我们还要定义这个bean的生产过程呀！这才是真正的目的。代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">@Component</span><br><span class="line">public class MyBeanPostProcessor implements BeanPostProcessor &#123;</span><br><span class="line">	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException &#123;</span><br><span class="line">		System.out.println(&quot;postProcessAfterInitialization  &quot;+ beanName);</span><br><span class="line">		return bean;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public Object postProcessBeforeInitialization(``````Object bean, String beanName) throws BeansException &#123;</span><br><span class="line">		System.out.println(&quot;postProcessBeforeInitialization &quot;+ beanName);</span><br><span class="line">		return bean;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>BeanPostProcessor接口作用是：如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理，我们就可以定义一个或者多个BeanPostProcessor接口的实现，然后注册到容器中。两个方法一个之前<br>一个之后。注册到容器时两个方法都会调，获取的时会调postProcessBeforeInitialization方法。我们可以在这里把bean在定制一番,怎么定制就看个人需求啦不再讲述。听SpringMvc就是采用的这种策略，没去验证过。第一种方法就介绍完了。</p>
<h3 id="2-扫描包解析注解"><a href="#2-扫描包解析注解" class="headerlink" title="2.扫描包解析注解"></a>2.扫描包解析注解</h3><ol>
<li>先定义注解代码如下：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">import java.lang.annotation.Documented;</span><br><span class="line">import java.lang.annotation.ElementType;</span><br><span class="line">import java.lang.annotation.Retention;</span><br><span class="line">import java.lang.annotation.RetentionPolicy;</span><br><span class="line">import java.lang.annotation.Target;</span><br><span class="line"></span><br><span class="line">@Target(&#123;ElementType.TYPE&#125;)</span><br><span class="line">@Retention(RetentionPolicy.RUNTIME)</span><br><span class="line">@Documented</span><br><span class="line">public @interface Component &#123;</span><br><span class="line">	String value() default &quot;&quot;;</span><br><span class="line">&#125;</span><br><span class="line">	</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>扫描 既然用到了Spring那么就让Spring来帮我们扫描代码如下：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">import java.util.Set;</span><br><span class="line">import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;</span><br><span class="line">import org.springframework.beans.factory.config.BeanDefinitionHolder;</span><br><span class="line">import org.springframework.beans.factory.support.BeanDefinitionRegistry;</span><br><span class="line">import org.springframework.beans.factory.support.GenericBeanDefinition;</span><br><span class="line">import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;</span><br><span class="line">import org.springframework.core.type.filter.AnnotationTypeFilter;</span><br><span class="line"></span><br><span class="line">public final class Scanner extends ClassPathBeanDefinitionScanner &#123;</span><br><span class="line"></span><br><span class="line">	public Scanner(BeanDefinitionRegistry registry) &#123;</span><br><span class="line">		super(registry);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public void registerDefaultFilters() &#123;</span><br><span class="line">		this.addIncludeFilter(new AnnotationTypeFilter(Component.class));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public Set&lt;BeanDefinitionHolder&gt; doScan(String... basePackages) &#123;</span><br><span class="line">		//super.doScan(basePackages) 会把生成的bean 加入Spring容器</span><br><span class="line">		Set&lt;BeanDefinitionHolder&gt; beanDefinitions = super.doScan(basePackages);</span><br><span class="line">		for (BeanDefinitionHolder holder : beanDefinitions) &#123;</span><br><span class="line">			GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();</span><br><span class="line">			// beanClassName给FactoryBeanImpl使用，还以再加几个Property</span><br><span class="line">			definition.getPropertyValues().add(&quot;beanClassName&quot;, definition.getBeanClassName()); </span><br><span class="line">			definition.setBeanClass(FactoryBeanImpl.class);</span><br><span class="line">		&#125;</span><br><span class="line">		return beanDefinitions;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) &#123;</span><br><span class="line">		return super.isCandidateComponent(beanDefinition) </span><br><span class="line">					&amp;&amp; (beanDefinition.getMetadata().hasAnnotation(Component.class.getName()));</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>上面的代码就是扫描，解析后得到的BeanDefinitionHolder 然后指定工厂FactoryBeanImpl生产后加入容器 代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">import org.springframework.beans.factory.FactoryBean;</span><br><span class="line">import org.springframework.beans.factory.InitializingBean;</span><br><span class="line">import org.springframework.cglib.core.SpringNamingPolicy;</span><br><span class="line">import org.springframework.cglib.proxy.Enhancer;</span><br><span class="line"></span><br><span class="line">public class FactoryBeanImpl&lt;T&gt; implements InitializingBean, FactoryBean&lt;T&gt; &#123;</span><br><span class="line">	private String beanClassName;</span><br><span class="line"> </span><br><span class="line">	public void setBeanClassName(String beanClassName) &#123;</span><br><span class="line">		this.beanClassName = beanClassName;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public T getObject() throws Exception &#123;</span><br><span class="line">		Class innerClass = Class.forName(beanClassName);</span><br><span class="line">		if (innerClass.isInterface()) &#123;//接口使用 jdk代理</span><br><span class="line">			return (T) InvocationHandlerImpl.newInstance(innerClass);</span><br><span class="line">		&#125; else &#123;//类使用 cglib代理</span><br><span class="line">			Enhancer enhancer = new Enhancer();</span><br><span class="line">			enhancer.setSuperclass(innerClass);</span><br><span class="line">			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);</span><br><span class="line">			enhancer.setCallback(new MethodInterceptorImpl());</span><br><span class="line">			return (T) enhancer.create();</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">		try &#123;</span><br><span class="line">			return Class.forName(beanClassName);</span><br><span class="line">		&#125; catch (ClassNotFoundException e) &#123;</span><br><span class="line">			e.printStackTrace();</span><br><span class="line">		&#125;</span><br><span class="line">		return null;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public boolean isSingleton() &#123;</span><br><span class="line">		return true;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public void afterPropertiesSet() throws Exception &#123;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个属性beanClassName是上面扫描绑定过来的。这里就是生成bean的工厂。getObject是bean的生成方法，代理就略过。代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">import java.lang.reflect.InvocationHandler;</span><br><span class="line">import java.lang.reflect.Method;</span><br><span class="line">import java.lang.reflect.Proxy;</span><br><span class="line">public class InvocationHandlerImpl implements InvocationHandler &#123;</span><br><span class="line">  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable &#123;</span><br><span class="line">      System.out.println(&quot;ObjectProxy execute:&quot; + method.getName());</span><br><span class="line">      return method.invoke(proxy, args);</span><br><span class="line">  &#125;</span><br><span class="line">  public static &lt;T&gt; T newInstance(Class&lt;T&gt; innerInterface) &#123;</span><br><span class="line">      ClassLoader classLoader = innerInterface.getClassLoader();</span><br><span class="line">      Class[] interfaces = new Class[] &#123; innerInterface &#125;;</span><br><span class="line">      InvocationHandlerImpl proxy = new InvocationHandlerImpl();</span><br><span class="line">      return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">import java.lang.reflect.Method;</span><br><span class="line">import org.springframework.cglib.proxy.MethodInterceptor;</span><br><span class="line">import org.springframework.cglib.proxy.MethodProxy;</span><br><span class="line"></span><br><span class="line">public class MethodInterceptorImpl implements MethodInterceptor &#123;</span><br><span class="line">	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable &#123;</span><br><span class="line">		System.out.println(&quot;MethodInterceptorImpl:&quot; + method.getName());</span><br><span class="line">		return methodProxy.invokeSuper(o, objects);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>3.什么都做了，什么时候扫描</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public Scanner(BeanDefinitionRegistry registry) &#123;</span><br><span class="line">    super(registry);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在实例化Scanner时需要 BeanDefinitionRegistry该类的作用主要是向注册表中注册 BeanDefinition实例 完成注册的过程。<br>BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后，在bean实例化之前执行的。<br>ConfigurableListableBeanFactory该类提供解析,修改bean定义,并与初始化单例.<br>在运行的时候传入的是 DefaultListableBeanFactory为 ConfigurableListableBeanFactory子类且实现了 BeanDefinitionRegistry<br>接口。代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br></pre></td><td class="code"><pre><span class="line">import org.springframework.beans.BeansException;</span><br><span class="line">import org.springframework.beans.factory.config.BeanFactoryPostProcessor;</span><br><span class="line">import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;</span><br><span class="line">import org.springframework.beans.factory.support.BeanDefinitionRegistry;</span><br><span class="line">import org.springframework.context.ApplicationContext;</span><br><span class="line">import org.springframework.context.ApplicationContextAware;</span><br><span class="line">import org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line">public class BeanFactoryPostProcesserImpl implements BeanFactoryPostProcessor, ApplicationContextAware &#123;</span><br><span class="line">	private ApplicationContext applicationContext;</span><br><span class="line"></span><br><span class="line">	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException &#123;</span><br><span class="line">		this.applicationContext = applicationContext;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException &#123;</span><br><span class="line">		Scanner scanner = new Scanner((BeanDefinitionRegistry) beanFactory);//可以强转</span><br><span class="line">		scanner.setResourceLoader(this.applicationContext);</span><br><span class="line">		scanner.setBeanNameGenerator(new AnnotationBeanNameGenerator());//解析注解得到value值。</span><br><span class="line">		scanner.scan(&quot;com.extend.service&quot;);//可以在xml配置进来 不再演示</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">import java.beans.Introspector;</span><br><span class="line">import java.util.Map;</span><br><span class="line">import java.util.Set;</span><br><span class="line"></span><br><span class="line">import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;</span><br><span class="line">import org.springframework.beans.factory.config.BeanDefinition;</span><br><span class="line">import org.springframework.beans.factory.support.BeanDefinitionRegistry;</span><br><span class="line">import org.springframework.beans.factory.support.BeanNameGenerator;</span><br><span class="line">import org.springframework.core.annotation.AnnotationAttributes;</span><br><span class="line">import org.springframework.core.type.AnnotationMetadata;</span><br><span class="line">import org.springframework.util.ClassUtils;</span><br><span class="line">import org.springframework.util.StringUtils;</span><br><span class="line"></span><br><span class="line">public class AnnotationBeanNameGenerator implements BeanNameGenerator &#123;</span><br><span class="line"></span><br><span class="line">	private static final String COMPONENT_ANNOTATION_CLASSNAME = &quot;com.extend.annotation2.Component&quot;;</span><br><span class="line"></span><br><span class="line">	@Override</span><br><span class="line">	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) &#123;</span><br><span class="line">		if (definition instanceof AnnotatedBeanDefinition) &#123;</span><br><span class="line">			String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);</span><br><span class="line">			if (StringUtils.hasText(beanName)) &#123;</span><br><span class="line">				return beanName;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		return buildDefaultBeanName(definition, registry);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) &#123;</span><br><span class="line">		AnnotationMetadata amd = annotatedDef.getMetadata();</span><br><span class="line">		Set&lt;String&gt; types = amd.getAnnotationTypes();</span><br><span class="line">		String beanName = null;</span><br><span class="line">		for (String type : types) &#123;</span><br><span class="line">			AnnotationAttributes attributes = AnnotationAttributes.fromMap(amd.getAnnotationAttributes(type, false));</span><br><span class="line">			// AnnotationAttributes attributes =</span><br><span class="line">			// AnnotationConfigUtils.attributesFor(amd, type);</span><br><span class="line">			if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) &#123;</span><br><span class="line">				Object value = attributes.get(&quot;value&quot;);</span><br><span class="line">				if (value instanceof String) &#123;</span><br><span class="line">					String strVal = (String) value;</span><br><span class="line">					if (StringUtils.hasLength(strVal)) &#123;</span><br><span class="line">					  if (beanName != null &amp;&amp; !strVal.equals(beanName)) &#123;</span><br><span class="line">						throw new IllegalStateException(&quot;Stereotype annotations suggest inconsistent &quot;</span><br><span class="line">								+ &quot;component names: &#x27;&quot; + beanName + &quot;&#x27; versus &#x27;&quot; + strVal + &quot;&#x27;&quot;);</span><br><span class="line">						&#125;</span><br><span class="line">						beanName = strVal;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		return beanName;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	protected boolean isStereotypeWithNameValue(String annotationType, Set&lt;String&gt; metaAnnotationTypes,</span><br><span class="line">			Map&lt;String, Object&gt; attributes) &#123;</span><br><span class="line"></span><br><span class="line">		boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME)</span><br><span class="line">			|| (metaAnnotationTypes != null &amp;&amp; metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME))</span><br><span class="line">			|| annotationType.equals(&quot;javax.annotation.ManagedBean&quot;) || annotationType.equals(&quot;javax.inject.Named&quot;);</span><br><span class="line"></span><br><span class="line">		return (isStereotype &amp;&amp; attributes != null &amp;&amp; attributes.containsKey(&quot;value&quot;));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) &#123;</span><br><span class="line">		return buildDefaultBeanName(definition);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	protected String buildDefaultBeanName(BeanDefinition definition) &#123;</span><br><span class="line">		String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());</span><br><span class="line">		return Introspector.decapitalize(shortClassName);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>以上就是实现过程 下面是测试：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">import com.extend.annotation2.Component;</span><br><span class="line">@Component(&quot;disCaver1&quot;)</span><br><span class="line">public class TestService &#123;</span><br><span class="line">	public String getName() &#123;</span><br><span class="line">		System.err.println(&quot;hello world!&quot;);</span><br><span class="line">		return &quot;hello world!&quot;;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">public class Test &#123;</span><br><span class="line">	public static void main(String[] args) throws Exception &#123;</span><br><span class="line">		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(&quot;classpath:spring-mybatis.xml&quot;);</span><br><span class="line">		context.start();</span><br><span class="line">		TestService disCaver1 = (TestService) context.getBean(&quot;disCaver1&quot;);</span><br><span class="line">		TestService disCaver2 = (TestService) context.getBean(TestService.class);</span><br><span class="line">		disCaver1.getName();</span><br><span class="line">		context.close();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line">	</span><br></pre></td></tr></table></figure>

<p>spring-mybatis.xml：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line">	&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">		xmlns:context=&quot;http://www.springframework.org/schema/context&quot; xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;</span><br><span class="line">		xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot; xmlns:dubbo=&quot;http://code.alibabatech.com/schema/dubbo&quot; </span><br><span class="line">		xmlns:cache=&quot;http://www.springframework.org/schema/cache&quot;</span><br><span class="line">		xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans    </span><br><span class="line">	           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    </span><br><span class="line">	           http://www.springframework.org/schema/context    </span><br><span class="line">	           http://www.springframework.org/schema/context/spring-context-3.0.xsd    </span><br><span class="line">	           http://www.springframework.org/schema/aop    </span><br><span class="line">	           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    </span><br><span class="line">	           http://www.springframework.org/schema/tx </span><br><span class="line">	           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd</span><br><span class="line">	           http://code.alibabatech.com/schema/dubbo </span><br><span class="line">			   http://code.alibabatech.com/schema/dubbo/dubbo.xsd&quot;&gt;</span><br><span class="line">			   &lt;bean class=&quot;com.extend.annotation2.BeanFactoryPostProcesserImpl&quot;/&gt;</span><br><span class="line">	&lt;/beans&gt;</span><br></pre></td></tr></table></figure>

<p>结果：<br>MethodInterceptorImpl:getName<br>hello world!</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://wenjies.github.io/2017/05/22/Spring%E6%89%A9%E5%B1%95/" data-id="cm3zaz9c20005tgu63va4ehvo" data-title="Spring扩展" class="article-share-link"><span class="fa fa-share">Teilen</span></a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E6%89%A9%E5%B1%95/" rel="tag">扩展</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2017/05/23/Spring%E4%B8%AD%E4%BA%8B%E5%8A%A1%E7%9A%84%E4%B8%80%E4%BA%9B%E7%89%B9%E6%80%A7/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Neuer</strong>
      <div class="article-nav-title">
        
          Spring中事务的一些特性
        
      </div>
    </a>
  
  
    <a href="/2017/05/17/java%E9%9D%A2%E8%AF%95%E6%80%BB%E7%BB%93/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Älter</strong>
      <div class="article-nav-title">JAVA面试总结</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Kategorien</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/AJAX/">AJAX</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA/">JAVA</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/MQ/">MQ</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Mybatis/">Mybatis</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Redis/">Redis</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Spring/">Spring</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/zookeeper/">zookeeper</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/">分布式事务</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B7%A5%E5%85%B7/">工具</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E7%BB%8F%E9%AA%8C/">经验</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/aop/" rel="tag">aop</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/bean/" rel="tag">bean</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/hexo/" rel="tag">hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java/" rel="tag">java</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/js/" rel="tag">js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/micrometer/" rel="tag">micrometer</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mvc/" rel="tag">mvc</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mybatis/" rel="tag">mybatis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mysql/" rel="tag">mysql</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/rocketmq/" rel="tag">rocketmq</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/spring/" rel="tag">spring</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/zookeeper/" rel="tag">zookeeper</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E4%BA%8B%E5%8A%A1/" rel="tag">事务</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/" rel="tag">分布式事务</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/" rel="tag">单元测试</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/" rel="tag">基础知识</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/" rel="tag">定时任务</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%89%A9%E5%B1%95/" rel="tag">扩展</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%95%B4%E5%90%88/" rel="tag">整合</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9D%A2%E8%AF%95/" rel="tag">面试</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/aop/" style="font-size: 10px;">aop</a> <a href="/tags/bean/" style="font-size: 10px;">bean</a> <a href="/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/tags/java/" style="font-size: 10px;">java</a> <a href="/tags/js/" style="font-size: 10px;">js</a> <a href="/tags/micrometer/" style="font-size: 10px;">micrometer</a> <a href="/tags/mvc/" style="font-size: 13.33px;">mvc</a> <a href="/tags/mybatis/" style="font-size: 10px;">mybatis</a> <a href="/tags/mysql/" style="font-size: 20px;">mysql</a> <a href="/tags/redis/" style="font-size: 10px;">redis</a> <a href="/tags/rocketmq/" style="font-size: 10px;">rocketmq</a> <a href="/tags/spring/" style="font-size: 10px;">spring</a> <a href="/tags/zookeeper/" style="font-size: 10px;">zookeeper</a> <a href="/tags/%E4%BA%8B%E5%8A%A1/" style="font-size: 10px;">事务</a> <a href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/" style="font-size: 10px;">分布式事务</a> <a href="/tags/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/" style="font-size: 10px;">单元测试</a> <a href="/tags/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/" style="font-size: 16.67px;">基础知识</a> <a href="/tags/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/" style="font-size: 10px;">定时任务</a> <a href="/tags/%E6%89%A9%E5%B1%95/" style="font-size: 10px;">扩展</a> <a href="/tags/%E6%95%B4%E5%90%88/" style="font-size: 10px;">整合</a> <a href="/tags/%E9%9D%A2%E8%AF%95/" style="font-size: 10px;">面试</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archiv</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2025/01/">January 2025</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/11/">November 2024</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/10/">October 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/09/">September 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/07/">July 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/05/">May 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/12/">December 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/11/">November 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/10/">October 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/08/">August 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/05/">May 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">March 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/02/">February 2016</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">letzter Beitrag</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2025/01/10/spring%20boot3%E6%95%B4%E5%90%88ELK%E5%AE%9E%E7%8E%B0%E6%97%A5%E5%BF%97%E6%90%9C%E7%B4%A2/">spring boot3整合ELK实现日志搜索</a>
          </li>
        
          <li>
            <a href="/2025/01/10/spring%20boot3%E6%95%B4%E5%90%88%E9%93%BE%E8%B7%AF%E8%BF%BD%E8%B8%AA/">spring boot3整合链路追踪</a>
          </li>
        
          <li>
            <a href="/2024/11/27/hexo%E4%BD%BF%E7%94%A8/">hexo使用</a>
          </li>
        
          <li>
            <a href="/2017/10/17/spring%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/">spring单元测试</a>
          </li>
        
          <li>
            <a href="/2017/09/16/jsonp%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82/">jsonp跨域请求</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2025 杰<br>
      <a href="https://beian.miit.gov.cn/" target="_blank">蜀ICP备19041392号-1</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/js/jquery-3.6.4.min.js"></script>



  
<script src="/fancybox/jquery.fancybox.min.js"></script>




<script src="/js/script.js"></script>





  </div>
</body>
</html>